Skip to content

feat: add oauth_token_cache_enabled to control kernel U2M on-disk token cache - #932

Queued
eric-wang-1990 wants to merge 9 commits into
mainfrom
eric-wang/kernel-token-cache-control
Queued

feat: add oauth_token_cache_enabled to control kernel U2M on-disk token cache#932
eric-wang-1990 wants to merge 9 commits into
mainfrom
eric-wang/kernel-token-cache-control

Conversation

@eric-wang-1990

@eric-wang-1990 eric-wang-1990 commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

What & why

Adds an oauth_token_cache_enabled: bool | None connection kwarg to control the kernel backend's U2M on-disk OAuth token cache.

On the kernel path with OAuth U2M (auth_type="oauth-u2m"), the Rust kernel can persist the refresh token to an AES-256 encrypted on-disk cache in the OS config dir (~/Library/Application Support/databricks-sql-kernel/oauth/ on macOS, ~/.config/databricks-sql-kernel/oauth/ on Linux), so a later process skips the interactive browser login. This threads a sql.connect(...) kwarg through to the pyo3 Session(token_cache_enabled=...) field.

Behavior

  • U2M-only. Forwarded only on the oauth-u2m branch; PAT/M2M/JWT paths omit it.
  • Disabled by default. When unset, the connector forwards token_cache_enabled=False — matching Thrift's in-memory (no on-disk persistence) posture, so migrating onto the kernel path doesn't silently start writing tokens to disk. Enabling is opt-in via oauth_token_cache_enabled=True.
  • Enable flag only for now (no passphrase surface); when enabled the kernel encrypts at rest with a machine-local derived key.
  • The existing Thrift-only experimental_oauth_persistence (custom OAuthPersistence store) is untouched — this new flag is a separate control and the kernel owns its own token lifecycle.

Dependency / why this is a draft

Consumes the pyo3 kwarg token_cache_enabled from databricks-sql-kernel PR #283, which is not yet released. The databricks-sql-kernel pin is intentionally left at ^0.2.0 (a bump to a nonexistent release would break install). Do not merge until:

  1. kernel PR Client automatically starts terminated clusters without any indication it has done so #283 is merged and a databricks-sql-kernel wheel ships with the kwarg, and
  2. this PR bumps the pin to that release (a follow-up commit here). Runtime E2E has already been validated against a locally-built kernel from Client automatically starts terminated clusters without any indication it has done so #283 (see Testing).

Note: because the connector always forwards token_cache_enabled on U2M, merging before the pin bump would raise TypeError: unexpected keyword argument against the current binding on every U2M connect — so the pin bump must land atomically with (or before) this reaching a released state.

Testing

  • Unit tests (pytest) for the U2M mapping: unset ⇒ False, TrueTrue, FalseFalse; applies to both databricks-oauth and azure-oauth; not forwarded on PAT/M2M (green locally — 24 in the token-cache/U2M subset). These mock the pyo3 Session.
  • Live kernel U2M E2E (macOS) against an Azure SQL warehouse, using a locally-built kernel wheel from the token_cache_enabled branch (databricks-sql-kernel rev e72b366, PR Client automatically starts terminated clusters without any indication it has done so #283). One connect per process, isolated to this connection's SHA-256 cache-key file (the shared cache dir was otherwise untouched). All three phases passed:
    • Enabled, fresh (oauth_token_cache_enabled=True, key file removed first): browser flow runs (Opening browser for OAuth authorization…), SELECT 1 returns 1, and the encrypted key file is written at 0o600.
    • Enabled, reuse (reconnect in a fresh process): Token cache hitno browser, query returns from the cached/refreshed token.
    • Disabled (oauth_token_cache_enabled=False, key file removed first): browser flow runs, query returns, and no cache file is written — confirming the disable-by-default posture. Unset behaves identically (both forward token_cache_enabled=False at the kernel boundary).

Related: databricks-sql-kernel PR #283.

This pull request and its description were written by Isaac.

…en cache

Adds the oauth_token_cache_enabled connect() kwarg, forwarded to the pyo3 Session token_cache_enabled field on the oauth-u2m path. U2M-only; disabled by default (matches Thrift no-persistence posture); enable-flag only; experimental_oauth_persistence is untouched.

Co-authored-by: Isaac
Signed-off-by: eric-wang-1990 <e.wang@databricks.com>
…TION_PARAMETERS.md

The connector forwards bool(None)=False on unset, so omitting the kwarg disables the on-disk cache; it does not inherit the kernel's enabled-by-default.

Co-authored-by: Isaac
Signed-off-by: eric-wang-1990 <e.wang@databricks.com>
@eric-wang-1990
eric-wang-1990 marked this pull request as ready for review August 26, 2026 00:09
Copilot AI lite review requested due to automatic review settings August 26, 2026 00:09

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new connection kwarg to control whether the kernel backend persists OAuth U2M refresh tokens to an encrypted on-disk cache, and threads that option through the kernel auth bridge to the kernel Session kwargs.

Changes:

  • Introduces oauth_token_cache_enabled: bool | None as a sql.connect(...) kwarg and documents it.
  • Plumbs the option through session/backend wiring so the kernel U2M path forwards token_cache_enabled.
  • Expands unit tests to validate defaulting/forwarding behavior and to ensure the flag is not forwarded on PAT/M2M paths.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/unit/test_kernel_auth_bridge.py Adds coverage for defaulting and forwarding of token_cache_enabled on U2M only.
src/databricks/sql/session.py Threads oauth_token_cache_enabled through kernel auth option collection (comment currently mismatches behavior).
src/databricks/sql/client.py Documents the new connect kwarg (doc currently mismatches behavior).
src/databricks/sql/backend/kernel/auth_bridge.py Forwards oauth_token_cache_enabled to the kernel’s token_cache_enabled (current coercion can mis-handle non-bool inputs).
CONNECTION_PARAMETERS.md Adds the new parameter to the connection parameter reference table.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/databricks/sql/backend/kernel/auth_bridge.py Outdated
Comment thread src/databricks/sql/session.py Outdated
Comment thread src/databricks/sql/client.py Outdated

@peco-review-bot peco-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: 2 Medium

Solid, well-tested change threading a new U2M-only oauth_token_cache_enabled kwarg to the kernel. Core logic and unit coverage look correct and match the disable-by-default design. Two medium doc/comment mismatches: the client.py docstring and the session.py comment both claim an unset value inherits the kernel's (enabled) default, but the code forwards False (disabled) — the reverse of the actual, and PR-intended, behavior.

Comment thread src/databricks/sql/client.py Outdated
Comment thread src/databricks/sql/session.py Outdated
@eric-wang-1990 eric-wang-1990 added the engineer-bot Maintainer-applied gate: triggers engineer-bot (bug-fix on issue / take-over on PR). label Aug 26, 2026
Addresses:
  - #3858601138 at src/databricks/sql/backend/kernel/auth_bridge.py:468
  - #3858601153 at src/databricks/sql/session.py:193
  - #3858601164 at src/databricks/sql/client.py:234

Signed-off-by: peco-engineer-bot[bot] <peco-engineer-bot[bot]@users.noreply.github.com>

@peco-review-bot peco-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: 1 Medium

Clean, well-scoped change that threads a new oauth_token_cache_enabled kwarg through to the kernel U2M branch, with thorough unit coverage (unset/False/True, truthy/falsey strings via _coerce_bool, and non-forwarding on PAT/M2M). Verdict: looks good — 1 medium, and it's the author's own documented do-not-merge blocker (the unconditional token_cache_enabled forward hard-couples to unreleased kernel PR #283, so merging before the pin bump breaks every U2M connect with a TypeError).

Minor nits (not filed inline): (1) _coerce_bool silently returns False for unknown types, diverging from the fail-loud ProgrammingError pattern in sibling helpers _normalize_scopes/_coerce_redirect_port — defensible as a fail-safe default and explicitly documented, but inconsistent. (2) A couple of the new explanatory comment lines in session.py/auth_bridge.py exceed the repo's 100-char limit (CONTRIBUTING.md). (3) The kernel_auth_kwargs docstrin

[...truncated to keep verdict scannable]

Comment thread src/databricks/sql/backend/kernel/auth_bridge.py Outdated

@peco-review-bot peco-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: 1 Low

Looks good — clean, well-tested addition of the oauth_token_cache_enabled kwarg. _coerce_bool correctly orders the bool-before-int check (so real booleans aren't misread), handles falsey DSN/env strings like "False", and the flag is correctly scoped to the U2M branch and excluded from PAT/M2M/JWT (all covered by unit tests). One low note on the known forward-compat merge gate. Nit: the client.py docstring and CONNECTION_PARAMETERS.md cite only the Linux cache path (~/.config/databricks-sql-kernel/oauth/); the PR description notes macOS uses ~/Library/Application Support/..., so the docs are slightly incomplete for macOS users.

Comment thread src/databricks/sql/backend/kernel/auth_bridge.py Outdated
…bled as Optional[bool]

oauth_token_cache_enabled is a typed connection kwarg like the connector's
other booleans (use_cloud_fetch, _use_arrow_native_complex_types, ...), none
of which coerce string inputs. Replace the one-off _coerce_bool with
`opts.get("oauth_token_cache_enabled") is True`: only a real True enables the
kernel's on-disk U2M token cache, and unset (None)/False forward an explicit
False so the kernel — whose own default is enabled — stays disabled by
default. Any non-bool value fails safe to disabled rather than silently
enabling.

Matches the nodejs connector's `tokenCacheEnabled ?? false` and removes the
inconsistency of coercing this one flag while every sibling boolean is passed
raw. Tests: the string-coercion cases are replaced by one asserting non-bool
inputs never enable the cache.

Signed-off-by: eric-wang-1990 <e.wang@databricks.com>

@peco-review-bot peco-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No issues identified by the review bot.

…nabled)

The token_cache_enabled field this PR forwards to the kernel exists in the
pyo3 Session only as of kernel #283. The prior pin (ad78a5b) lacks it, so the
flag reached a kernel that ignored it. Bump to 628abd6 (kernel main HEAD):
its pyo3 Session signature is a backward-compatible superset of ad78a5b's
(identical azure-SP params, plus token_cache_enabled/_passphrase), so the
kernel-e2e CI builds a kernel that honors the flag. Verified E2E (U2M):
unset => no on-disk cache; True => encrypted cache file written.

Published databricks-sql-kernel pin stays ^0.2.0 (no 0.2.1 pyo3 wheel yet);
KERNEL_REV is what the kernel-e2e workflow builds the wheel from.

Signed-off-by: eric-wang-1990 <e.wang@databricks.com>
Resolves the KERNEL_REV conflict: main pins dd810d6 (#288, request timeout);
this branch pins 628abd6 (#283, token cache). dd810d6 is an ancestor of
628abd6, so 628abd6 carries both the request-timeout and token-cache kernel
changes — keep 628abd6. All other files auto-merged (disjoint regions:
token-cache vs socket-timeout).

Signed-off-by: eric-wang-1990 <e.wang@databricks.com>

@peco-review-bot peco-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: 1 Low

Clean, well-tested addition of the oauth_token_cache_enabled kwarg. The bridge correctly forwards token_cache_enabled only on the oauth-u2m branch as opts.get(...) is True, implementing the documented disable-by-default posture; PAT/M2M/JWT paths are unaffected and covered by tests. No correctness or coverage concerns. One low doc-accuracy note inline. Note the PR is a draft blocked on the databricks-sql-kernel pin bump (already called out in the description) — not re-raised here.

Comment thread src/databricks/sql/client.py Outdated
Addresses:
  - #3860320318 at src/databricks/sql/client.py:230

Signed-off-by: peco-engineer-bot[bot] <peco-engineer-bot[bot]@users.noreply.github.com>

@peco-review-bot peco-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No issues identified by the review bot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

engineer-bot Maintainer-applied gate: triggers engineer-bot (bug-fix on issue / take-over on PR).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants